using System;
using System.Data;
using System.Xml;
using System.Runtime.Serialization;
using System.Collections;
using System.Collections.Generic;
using Widgetsphere.Core.Logging;
using Widgetsphere.Core.Exceptions;
using Widgetsphere.Core.DataAccess;
using ACME.Northwind.Business;
using ACME.Northwind.Business.Rules;
using Widgetsphere.Core.WinUI;
using ACME.Northwind.Domain.Objects;
using System.ComponentModel;
using Widgetsphere.Core.EventArgs;
using ACME.Northwind.Business.Objects.Composites;
using System.IO;

namespace ACME.Northwind.Business.Objects
{
	/// <summary>
	/// Interface definition for the 'Product' entity
	/// </summary>
	public interface IProduct : IPersistableBusinessObject, IAuditable, ICloneable
	{
		#region Properties

		/// <summary>
		/// The CategoryId field
		/// </summary>
		int? CategoryId { get; set; }
		/// <summary>
		/// The Discontinued field
		/// </summary>
		bool Discontinued { get; set; }
		/// <summary>
		/// The ProductId field
		/// </summary>
		int ProductId { get; }
		/// <summary>
		/// The ProductName field
		/// </summary>
		string ProductName { get; set; }
		/// <summary>
		/// The QuantityPerUnit field
		/// </summary>
		string QuantityPerUnit { get; set; }
		/// <summary>
		/// The ReorderLevel field
		/// </summary>
		short? ReorderLevel { get; set; }
		/// <summary>
		/// The SupplierId field
		/// </summary>
		int? SupplierId { get; set; }
		/// <summary>
		/// The UnitPrice field
		/// </summary>
		decimal? UnitPrice { get; set; }
		/// <summary>
		/// The UnitsInStock field
		/// </summary>
		short? UnitsInStock { get; set; }
		/// <summary>
		/// The UnitsOnOrder field
		/// </summary>
		short? UnitsOnOrder { get; set; }

		#endregion

		#region Methods

		/// <summary>
		/// This event is called before persisting to the database.
		/// </summary>
		event EventHandler<BusinessObjectEventArgs> Validate;

		/// <summary>
		/// Removes this object from its parent collection. It will not be deleted from the database.
		/// </summary>
		void Remove();

		/// <summary>
		/// The primary key for this object
		/// </summary>
		new ProductPrimaryKey PrimaryKey { get; }

		/// <summary>
		/// Persists this object to the database.
		/// </summary>
		new void Persist();

		/// <summary>
		/// Creates a clone of this object.
		/// </summary>
		new IBusinessObject Clone();

		#endregion

	}

	/// <summary>
	/// Class definition for the 'Product' entity
	/// </summary>
	[Serializable()]
	public partial class Product : BusinessObjectPersistableBase, IPersistableBusinessObject, IProduct
	{
		#region Class Members

		#region FieldNameConstants Enumeration

		/// <summary>
		/// Enumeration to define each property that maps to a database field for the 'Product' table.
		/// </summary>
		public enum FieldNameConstants
		{
			 /// <summary>
			 /// Field mapping for the 'CategoryId' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'CategoryId' property")]
			CategoryId,
			 /// <summary>
			 /// Field mapping for the 'UnitsOnOrder' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'UnitsOnOrder' property")]
			UnitsOnOrder,
			 /// <summary>
			 /// Field mapping for the 'UnitsInStock' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'UnitsInStock' property")]
			UnitsInStock,
			 /// <summary>
			 /// Field mapping for the 'UnitPrice' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'UnitPrice' property")]
			UnitPrice,
			 /// <summary>
			 /// Field mapping for the 'SupplierId' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'SupplierId' property")]
			SupplierId,
			 /// <summary>
			 /// Field mapping for the 'ReorderLevel' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'ReorderLevel' property")]
			ReorderLevel,
			 /// <summary>
			 /// Field mapping for the 'QuantityPerUnit' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'QuantityPerUnit' property")]
			QuantityPerUnit,
			 /// <summary>
			 /// Field mapping for the 'ProductName' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'ProductName' property")]
			ProductName,
			 /// <summary>
			 /// Field mapping for the 'ProductId' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'ProductId' property")]
			ProductId,
			 /// <summary>
			 /// Field mapping for the 'Discontinued' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'Discontinued' property")]
			Discontinued,
			 /// <summary>
			 /// Field mapping for the 'CreatedBy' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'CreatedBy' property")]
			CreatedBy,
			 /// <summary>
			 /// Field mapping for the 'CreatedDate' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'CreatedDate' property")]
			CreatedDate,
			 /// <summary>
			 /// Field mapping for the 'ModifiedBy' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'ModifiedBy' property")]
			ModifiedBy,
			 /// <summary>
			 /// Field mapping for the 'ModifiedDate' property
			 /// </summary>
			[System.ComponentModel.Description("Field mapping for the 'ModifiedDate' property")]
			ModifiedDate,
		}
		#endregion

		internal DomainProduct wrappedClass;

		#endregion

		#region Constructors

		/// <summary>
		/// Creates a 'Product' object from a domain object
		/// </summary>
		internal Product(DomainProduct classToWrap)
		{
			wrappedClass = classToWrap;
		}

		/// <summary>
		/// Creates a 'Product' object from a DataRowView
		/// </summary>
		internal Product(DataRowView drvToWrap)
		{
			wrappedClass = (DomainProduct)drvToWrap.Row;
		}

		#endregion

		#region Events

		/// <summary>
		/// This event is raised before the 'CategoryId' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<int?>> CategoryIdChanging;

		/// <summary>
		/// This event is raised when the 'CategoryId' field is changed.
		/// </summary>
		public event EventHandler CategoryIdChanged;

		/// <summary>
		/// This event is raised before the 'Discontinued' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<bool>> DiscontinuedChanging;

		/// <summary>
		/// This event is raised when the 'Discontinued' field is changed.
		/// </summary>
		public event EventHandler DiscontinuedChanged;

		/// <summary>
		/// This event is raised before the 'ProductId' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<int>> ProductIdChanging;

		/// <summary>
		/// This event is raised when the 'ProductId' field is changed.
		/// </summary>
		public event EventHandler ProductIdChanged;

		/// <summary>
		/// This event is raised before the 'ProductName' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<string>> ProductNameChanging;

		/// <summary>
		/// This event is raised when the 'ProductName' field is changed.
		/// </summary>
		public event EventHandler ProductNameChanged;

		/// <summary>
		/// This event is raised before the 'QuantityPerUnit' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<string>> QuantityPerUnitChanging;

		/// <summary>
		/// This event is raised when the 'QuantityPerUnit' field is changed.
		/// </summary>
		public event EventHandler QuantityPerUnitChanged;

		/// <summary>
		/// This event is raised before the 'ReorderLevel' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<short?>> ReorderLevelChanging;

		/// <summary>
		/// This event is raised when the 'ReorderLevel' field is changed.
		/// </summary>
		public event EventHandler ReorderLevelChanged;

		/// <summary>
		/// This event is raised before the 'SupplierId' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<int?>> SupplierIdChanging;

		/// <summary>
		/// This event is raised when the 'SupplierId' field is changed.
		/// </summary>
		public event EventHandler SupplierIdChanged;

		/// <summary>
		/// This event is raised before the 'UnitPrice' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<decimal?>> UnitPriceChanging;

		/// <summary>
		/// This event is raised when the 'UnitPrice' field is changed.
		/// </summary>
		public event EventHandler UnitPriceChanged;

		/// <summary>
		/// This event is raised before the 'UnitsInStock' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<short?>> UnitsInStockChanging;

		/// <summary>
		/// This event is raised when the 'UnitsInStock' field is changed.
		/// </summary>
		public event EventHandler UnitsInStockChanged;

		/// <summary>
		/// This event is raised before the 'UnitsOnOrder' field is changed providing a chance to cancel the action.
		/// </summary>
		public event EventHandler<BusinessObjectCancelEventArgs<short?>> UnitsOnOrderChanging;

		/// <summary>
		/// This event is raised when the 'UnitsOnOrder' field is changed.
		/// </summary>
		public event EventHandler UnitsOnOrderChanged;

		/// <summary>
		/// Raises the CategoryIdChanging event.
		/// </summary>
		protected virtual void OnCategoryIdChanging(BusinessObjectCancelEventArgs<int?> e)
		{
			if (this.CategoryIdChanging != null)
				this.CategoryIdChanging(this, e);
		}

		/// <summary>
		/// Raises the CategoryIdChanged event.
		/// </summary>
		protected virtual void OnCategoryIdChanged(System.EventArgs e)
		{
			if (this.CategoryIdChanged != null)
				this.CategoryIdChanged(this, e);
		}

		/// <summary>
		/// Raises the DiscontinuedChanging event.
		/// </summary>
		protected virtual void OnDiscontinuedChanging(BusinessObjectCancelEventArgs<bool> e)
		{
			if (this.DiscontinuedChanging != null)
				this.DiscontinuedChanging(this, e);
		}

		/// <summary>
		/// Raises the DiscontinuedChanged event.
		/// </summary>
		protected virtual void OnDiscontinuedChanged(System.EventArgs e)
		{
			if (this.DiscontinuedChanged != null)
				this.DiscontinuedChanged(this, e);
		}

		/// <summary>
		/// Raises the ProductIdChanging event.
		/// </summary>
		protected virtual void OnProductIdChanging(BusinessObjectCancelEventArgs<int> e)
		{
			if (this.ProductIdChanging != null)
				this.ProductIdChanging(this, e);
		}

		/// <summary>
		/// Raises the ProductIdChanged event.
		/// </summary>
		protected virtual void OnProductIdChanged(System.EventArgs e)
		{
			if (this.ProductIdChanged != null)
				this.ProductIdChanged(this, e);
		}

		/// <summary>
		/// Raises the ProductNameChanging event.
		/// </summary>
		protected virtual void OnProductNameChanging(BusinessObjectCancelEventArgs<string> e)
		{
			if (this.ProductNameChanging != null)
				this.ProductNameChanging(this, e);
		}

		/// <summary>
		/// Raises the ProductNameChanged event.
		/// </summary>
		protected virtual void OnProductNameChanged(System.EventArgs e)
		{
			if (this.ProductNameChanged != null)
				this.ProductNameChanged(this, e);
		}

		/// <summary>
		/// Raises the QuantityPerUnitChanging event.
		/// </summary>
		protected virtual void OnQuantityPerUnitChanging(BusinessObjectCancelEventArgs<string> e)
		{
			if (this.QuantityPerUnitChanging != null)
				this.QuantityPerUnitChanging(this, e);
		}

		/// <summary>
		/// Raises the QuantityPerUnitChanged event.
		/// </summary>
		protected virtual void OnQuantityPerUnitChanged(System.EventArgs e)
		{
			if (this.QuantityPerUnitChanged != null)
				this.QuantityPerUnitChanged(this, e);
		}

		/// <summary>
		/// Raises the ReorderLevelChanging event.
		/// </summary>
		protected virtual void OnReorderLevelChanging(BusinessObjectCancelEventArgs<short?> e)
		{
			if (this.ReorderLevelChanging != null)
				this.ReorderLevelChanging(this, e);
		}

		/// <summary>
		/// Raises the ReorderLevelChanged event.
		/// </summary>
		protected virtual void OnReorderLevelChanged(System.EventArgs e)
		{
			if (this.ReorderLevelChanged != null)
				this.ReorderLevelChanged(this, e);
		}

		/// <summary>
		/// Raises the SupplierIdChanging event.
		/// </summary>
		protected virtual void OnSupplierIdChanging(BusinessObjectCancelEventArgs<int?> e)
		{
			if (this.SupplierIdChanging != null)
				this.SupplierIdChanging(this, e);
		}

		/// <summary>
		/// Raises the SupplierIdChanged event.
		/// </summary>
		protected virtual void OnSupplierIdChanged(System.EventArgs e)
		{
			if (this.SupplierIdChanged != null)
				this.SupplierIdChanged(this, e);
		}

		/// <summary>
		/// Raises the UnitPriceChanging event.
		/// </summary>
		protected virtual void OnUnitPriceChanging(BusinessObjectCancelEventArgs<decimal?> e)
		{
			if (this.UnitPriceChanging != null)
				this.UnitPriceChanging(this, e);
		}

		/// <summary>
		/// Raises the UnitPriceChanged event.
		/// </summary>
		protected virtual void OnUnitPriceChanged(System.EventArgs e)
		{
			if (this.UnitPriceChanged != null)
				this.UnitPriceChanged(this, e);
		}

		/// <summary>
		/// Raises the UnitsInStockChanging event.
		/// </summary>
		protected virtual void OnUnitsInStockChanging(BusinessObjectCancelEventArgs<short?> e)
		{
			if (this.UnitsInStockChanging != null)
				this.UnitsInStockChanging(this, e);
		}

		/// <summary>
		/// Raises the UnitsInStockChanged event.
		/// </summary>
		protected virtual void OnUnitsInStockChanged(System.EventArgs e)
		{
			if (this.UnitsInStockChanged != null)
				this.UnitsInStockChanged(this, e);
		}

		/// <summary>
		/// Raises the UnitsOnOrderChanging event.
		/// </summary>
		protected virtual void OnUnitsOnOrderChanging(BusinessObjectCancelEventArgs<short?> e)
		{
			if (this.UnitsOnOrderChanging != null)
				this.UnitsOnOrderChanging(this, e);
		}

		/// <summary>
		/// Raises the UnitsOnOrderChanged event.
		/// </summary>
		protected virtual void OnUnitsOnOrderChanged(System.EventArgs e)
		{
			if (this.UnitsOnOrderChanged != null)
				this.UnitsOnOrderChanged(this, e);
		}

		#endregion

		#region Properties

		/// <summary>
		/// The current state of this object.
		/// </summary>
		public Widgetsphere.Core.DataAccess.SubDomainBase.ItemStateConstants ItemState
		{
			get { return (Widgetsphere.Core.DataAccess.SubDomainBase.ItemStateConstants)int.Parse(wrappedClass.RowState.ToString("d")); }
		}

		/// <summary>
		/// Determines the type of collection that contains this object.
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		public Collections Container
		{
			get { return Collections.ProductCollection; }
		}

		#region CreatedBy / ModifiedBy Section

		/// <summary>
		/// The audit field for the 'Modified By' column.
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		public virtual string ModifiedBy
		{
			get
			{
				object o = this.wrappedClass[this.wrappedClass.ParentCol.ModifiedByColumn];
				if (o == DBNull.Value) return null;
				else return (string)o;
			}
			internal set { this.wrappedClass[this.wrappedClass.ParentCol.ModifiedByColumn] = value; }
		}

		/// <summary>
		/// The audit field for the 'Modified Date' column.
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		public virtual DateTime? ModifiedDate
		{
			get
			{
				object o = this.wrappedClass[this.wrappedClass.ParentCol.ModifiedDateColumn];
				if (o == DBNull.Value) return null;
				else return (DateTime)o;
			}
			internal set { this.wrappedClass[this.wrappedClass.ParentCol.ModifiedDateColumn] = value; }
		}

		/// <summary>
		/// Sets 'ModifiedBy' column.
		/// </summary>
		public virtual void SetModifiedDate(DateTime newValue)
		{
			this.wrappedClass[this.wrappedClass.ParentCol.ModifiedDateColumn] = newValue;
		}

		/// <summary>
		/// The audit field for the 'Created By' column.
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		public virtual string CreatedBy
		{
			get
			{
				object o = this.wrappedClass[this.wrappedClass.ParentCol.CreatedByColumn];
				if (o == DBNull.Value) return null;
				else return (string)o;
			}
			internal set { this.wrappedClass[this.wrappedClass.ParentCol.CreatedByColumn] = value; }
		}

		/// <summary>
		/// The audit field for the 'Created Date' column.
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		public virtual DateTime? CreatedDate
		{
			get
			{
				object o = this.wrappedClass[this.wrappedClass.ParentCol.CreatedDateColumn];
				if (o == DBNull.Value) return null;
				else return (DateTime)o;
			}
			internal set { this.wrappedClass[this.wrappedClass.ParentCol.CreatedDateColumn] = value; }
		}

		/// <summary>
		/// Sets 'ModifiedBy' column.
		/// </summary>
		public virtual void SetCreatedDate(DateTime newValue)
		{
			this.wrappedClass[this.wrappedClass.ParentCol.CreatedDateColumn] = newValue;
		}

		[System.ComponentModel.Browsable(false)]
		internal virtual byte[] TimeStamp
		{
			get
			{
				 object o = this.wrappedClass[this.wrappedClass.ParentCol.TimeStampColumn];
				 return (byte[])o;
			}
			set { this.wrappedClass[this.wrappedClass.ParentCol.TimeStampColumn] = value; }
		}

		#endregion

		/// <summary>
		/// Determines if this object is part of a collection or is detached
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		public virtual bool IsParented
		{
		  get { return (((DataRow)this.WrappedClass).RowState != DataRowState.Detached); }
		}

		/// <summary>
		/// Returns the internal object that this object wraps
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		internal virtual object WrappedClass
		{
			get{ return wrappedClass; }
			set{ wrappedClass = (DomainProduct)value; }
		}

		//WrappingClass Interface
		object IWrappingClass.WrappedClass
		{
			get { return this.WrappedClass; }
			set { this.WrappedClass = value; }
		}

		/// <summary>
		/// The primary key for this object
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		public virtual ProductPrimaryKey PrimaryKey
		{
			get
			{
				try
				{
					return wrappedClass.PrimaryKey;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		/// <summary>
		/// Property for table field: CategoryID
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual int? CategoryId
		{
			get
			{
				try { return wrappedClass.CategoryId; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{

					BusinessObjectCancelEventArgs<int?> cancelArgs = new BusinessObjectCancelEventArgs<int?>(value);
					this.OnCategoryIdChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.CategoryId = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("CategoryId"));
						this.OnCategoryIdChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: Discontinued
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual bool Discontinued
		{
			get
			{
				try { return wrappedClass.Discontinued; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{
					BusinessObjectCancelEventArgs<bool> cancelArgs = new BusinessObjectCancelEventArgs<bool>(value);
					this.OnDiscontinuedChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.Discontinued = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("Discontinued"));
						this.OnDiscontinuedChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: ProductID
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual int ProductId
		{
			get
			{
				try { return wrappedClass.ProductId; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		/// <summary>
		/// Property for table field: ProductName
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual string ProductName
		{
			get
			{
				try { return wrappedClass.ProductName; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				if ((value != null) && (value.Length > GetMaxLength(FieldNameConstants.ProductName))) throw new Exception(string.Format(GlobalValues.ERROR_DATA_TOO_BIG, value, "Product.ProductName", GetMaxLength(FieldNameConstants.ProductName)));
				try
				{
					BusinessObjectCancelEventArgs<string> cancelArgs = new BusinessObjectCancelEventArgs<string>(value);
					this.OnProductNameChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.ProductName = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("ProductName"));
						this.OnProductNameChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: QuantityPerUnit
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual string QuantityPerUnit
		{
			get
			{
				try { return wrappedClass.QuantityPerUnit; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				if ((value != null) && (value.Length > GetMaxLength(FieldNameConstants.QuantityPerUnit))) throw new Exception(string.Format(GlobalValues.ERROR_DATA_TOO_BIG, value, "Product.QuantityPerUnit", GetMaxLength(FieldNameConstants.QuantityPerUnit)));
				try
				{
					BusinessObjectCancelEventArgs<string> cancelArgs = new BusinessObjectCancelEventArgs<string>(value);
					this.OnQuantityPerUnitChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.QuantityPerUnit = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("QuantityPerUnit"));
						this.OnQuantityPerUnitChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: ReorderLevel
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual short? ReorderLevel
		{
			get
			{
				try { return wrappedClass.ReorderLevel; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{

					BusinessObjectCancelEventArgs<short?> cancelArgs = new BusinessObjectCancelEventArgs<short?>(value);
					this.OnReorderLevelChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.ReorderLevel = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("ReorderLevel"));
						this.OnReorderLevelChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: SupplierID
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual int? SupplierId
		{
			get
			{
				try { return wrappedClass.SupplierId; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{

					BusinessObjectCancelEventArgs<int?> cancelArgs = new BusinessObjectCancelEventArgs<int?>(value);
					this.OnSupplierIdChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.SupplierId = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("SupplierId"));
						this.OnSupplierIdChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: UnitPrice
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual decimal? UnitPrice
		{
			get
			{
				try { return wrappedClass.UnitPrice; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{
					BusinessObjectCancelEventArgs<decimal?> cancelArgs = new BusinessObjectCancelEventArgs<decimal?>(value);
					this.OnUnitPriceChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.UnitPrice = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("UnitPrice"));
						this.OnUnitPriceChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: UnitsInStock
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual short? UnitsInStock
		{
			get
			{
				try { return wrappedClass.UnitsInStock; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{

					BusinessObjectCancelEventArgs<short?> cancelArgs = new BusinessObjectCancelEventArgs<short?>(value);
					this.OnUnitsInStockChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.UnitsInStock = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("UnitsInStock"));
						this.OnUnitsInStockChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		/// <summary>
		/// Property for table field: UnitsOnOrder
		/// </summary>
		[System.ComponentModel.Browsable(true)]
		[System.ComponentModel.Description("")]
		[Widgetsphere.Core.Attributes.DataSetting("", false, 0)]
		public virtual short? UnitsOnOrder
		{
			get
			{
				try { return wrappedClass.UnitsOnOrder; }
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{

					BusinessObjectCancelEventArgs<short?> cancelArgs = new BusinessObjectCancelEventArgs<short?>(value);
					this.OnUnitsOnOrderChanging(cancelArgs);
					if (!cancelArgs.Cancel)
					{
						lock (this)
						{
							wrappedClass.UnitsOnOrder = cancelArgs.NewValue;
						}
						this.ModifiedDate = DateTime.Now;
						this.OnPropertyChanged(new PropertyChangedEventArgs("UnitsOnOrder"));
						this.OnUnitsOnOrderChanged(new EventArgs());
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}

		}

		internal virtual void ReleaseNonIdentifyingRelationships()
		{
			try
			{
				wrappedClass.ReleaseNonIdentifyingRelationships();
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// A list of related 'OrderDetail' items
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		public virtual BusinessObjectList<OrderDetail> OrderDetailList
		{
			get
			{
				try
				{
					if (this.ParentCollection == null)
					{
						lock (this)
						{
							return wrappedClass.OrderDetailList;
						}
					}
					else
					{
						lock (this.ParentCollection.SubDomain)
						{
							return wrappedClass.OrderDetailList;
						}
					}
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		/// <summary>
		/// Gets or sets the related 'Category' object.
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		public virtual Category CategoryItem
		{
			get
			{
				try
				{
					if (wrappedClass.CategoryItem != null) return new Category(wrappedClass.CategoryItem);
					else return null;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{
					wrappedClass.CategoryItem = value.wrappedClass;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}
		/// <summary>
		/// Gets or sets the related 'Supplier' object.
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		public virtual Supplier SupplierItem
		{
			get
			{
				try
				{
					if (wrappedClass.SupplierItem != null) return new Supplier(wrappedClass.SupplierItem);
					else return null;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
			set
			{
				try
				{
					wrappedClass.SupplierItem = value.wrappedClass;
				}
				catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
				catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
				catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
			}
		}

		#endregion

		#region Collection Operation Methods

		/// <summary>
		/// This event is called before persisting to the database.
		/// </summary>
		public event EventHandler<BusinessObjectEventArgs> Validate;

		/// <summary>
		/// This event is called before persisting to store.
		/// </summary>
		/// <param name="item"></param>
		protected internal void OnValidate(BusinessObjectEventArgs item)
		{
			if (this.Validate != null)
				this.Validate(this, item);
		}

		/// <summary>
		/// Persists this object to the database.
		/// </summary>
		public override void Persist()
		{
		  if (this.IsParented)
		  {
				this.OnValidate(new BusinessObjectEventArgs(this));
			  wrappedClass.Persist();
		  }
		  else
		    throw new Exception("This item is not part of a collection and cannot be persisted!");
		}

		/// <summary>
		/// Removes this object from its parent collection. It will not be deleted from the database.
		/// </summary>
		public void Remove()
		{
			try
			{
				if (this.ParentCollection == null)
				{
					lock (this)
					{
						wrappedClass.Remove();
					}
				}
				else
				{
					lock (this.ParentCollection.SubDomain)
					{
						wrappedClass.Remove();
					}
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		/// <summary>
		/// Marks this object for deletion. The next call to the Persist method will delete it from the database.
		/// </summary>
		public void Delete()
		{
			try
			{
				if (this.ParentCollection == null)
				{
					lock (this)
					{
						wrappedClass.Delete();
					}
				}
				else
				{
					lock (this.ParentCollection.SubDomain)
					{
						wrappedClass.Delete();
					}
				}
			}
			catch (System.Data.DBConcurrencyException dbcex) { throw new ConcurrencyException(GlobalValues.ERROR_CONCURRENCY_FAILURE, dbcex); }
			catch (System.Data.SqlClient.SqlException sqlexp) { if (sqlexp.Number == 547 || sqlexp.Number == 2627) throw new UniqueConstraintViolatedException(GlobalValues.ERROR_CONSTRAINT_FAILURE, sqlexp); else throw; }
			catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); throw; }
		}

		#endregion

		#region Overrides

		/// <summary>
		/// Serves as a hash function for this particular type.
		/// </summary>
		public override int GetHashCode()
		{
			return base.GetHashCode();
		}

		/// <summary>
		/// Returns a value indicating whether the current object is equal to a specified object.
		/// </summary>
		public override bool Equals(object obj)
		{
			if (obj == null) return false;
			if (obj.GetType() == this.GetType())
			{
				if (this.wrappedClass.Equals(((Product)obj).wrappedClass))
					return true;
			}
			else if(obj.GetType() == this.PrimaryKey.GetType())
			{
			  if(this.PrimaryKey.Equals(obj))
			    return true;
			}
			else if (obj.GetType() == this.PrimaryKey.ProductId.GetType())
			{
				if (this.PrimaryKey.ProductId.Equals(obj))
					return true;
			}
			return false;
		}

		#endregion

		#region IBusinessObject ParentCollection

		/// <summary>
		/// This is a reference back to the generic collection that holds this object.
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		IBusinessCollection IBusinessObject.ParentCollection
		{
			get { return this.ParentCollection; }
		}

		#endregion

		#region ParentCollection

		/// <summary>
		/// This is a reference back to the collection that holds this object.
		/// </summary>
		[System.ComponentModel.Browsable(false)]
		public ProductCollection ParentCollection
		{
			get { return new ProductCollection(wrappedClass.ParentCol); }
		}

		#endregion

		#region GetDefault

		/// <summary>
		/// Gets the default value of one of this object's properties.
		/// </summary>
		public object GetDefault(FieldNameConstants field)
		{
			if(field == FieldNameConstants.CategoryId)
				return null;
			if(field == FieldNameConstants.Discontinued)
				return false;
			if(field == FieldNameConstants.ProductId)
				return 0;
			if(field == FieldNameConstants.ProductName)
				return "";
			if(field == FieldNameConstants.QuantityPerUnit)
				return "";
			if(field == FieldNameConstants.ReorderLevel)
				return null;
			if(field == FieldNameConstants.SupplierId)
				return null;
			if(field == FieldNameConstants.UnitPrice)
				return null;
			if(field == FieldNameConstants.UnitsInStock)
				return null;
			if(field == FieldNameConstants.UnitsOnOrder)
				return null;

			return null;
		}

		object IBusinessObject.GetDefault(Enum field)
		{
			return this.GetDefault((FieldNameConstants)field);
		}

		#endregion

		#region GetValue

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public object GetValue(FieldNameConstants field)
		{
			return GetValue(field, null);
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public object GetValue(FieldNameConstants field, object defaultValue)
		{
			if(field == FieldNameConstants.CategoryId)
				return ((this.CategoryId == null) ? defaultValue : this.CategoryId);
			if(field == FieldNameConstants.UnitsOnOrder)
				return ((this.UnitsOnOrder == null) ? defaultValue : this.UnitsOnOrder);
			if(field == FieldNameConstants.UnitsInStock)
				return ((this.UnitsInStock == null) ? defaultValue : this.UnitsInStock);
			if(field == FieldNameConstants.UnitPrice)
				return ((this.UnitPrice == null) ? defaultValue : this.UnitPrice);
			if(field == FieldNameConstants.SupplierId)
				return ((this.SupplierId == null) ? defaultValue : this.SupplierId);
			if(field == FieldNameConstants.ReorderLevel)
				return ((this.ReorderLevel == null) ? defaultValue : this.ReorderLevel);
			if(field == FieldNameConstants.QuantityPerUnit)
				return ((this.QuantityPerUnit == null) ? defaultValue : this.QuantityPerUnit);
			if(field == FieldNameConstants.ProductName)
				return this.ProductName;
			if(field == FieldNameConstants.ProductId)
				return this.ProductId;
			if(field == FieldNameConstants.Discontinued)
				return this.Discontinued;
			throw new Exception("Field '" + field.ToString() + "' not found!");
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public int GetInteger(FieldNameConstants field)
		{
			return this.GetInteger(field, int.MinValue);
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public int GetInteger(FieldNameConstants field, int defaultValue)
		{
			object o = this.GetValue(field, defaultValue);
			if (o is string)
			{
				int a;
				if (int.TryParse((string)o, out a))
					return a;
				else
					throw new InvalidCastException();
			}
			else
			{
				return (int)o;
			}
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public double GetDouble(FieldNameConstants field)
		{
			return this.GetDouble(field, double.MinValue);
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public double GetDouble(FieldNameConstants field, double defaultValue)
		{
			object o = this.GetValue(field, defaultValue);
			if (o is string)
			{
				double a;
				if (double.TryParse((string)o, out a))
					return a;
				else
					throw new InvalidCastException();
			}
			else
			{
				return (double)o;
			}
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public DateTime GetDateTime(FieldNameConstants field)
		{
			return this.GetDateTime(field, DateTime.MinValue);
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public DateTime GetDateTime(FieldNameConstants field, DateTime defaultValue)
		{
			object o = this.GetValue(field, defaultValue);
			if (o is string)
			{
				DateTime a;
				if (DateTime.TryParse((string)o, out a))
					return a;
				else
					throw new InvalidCastException();
			}
			else
			{
				return (DateTime)o;
			}
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public string GetString(FieldNameConstants field)
		{
			return this.GetString(field, "");
		}

		/// <summary>
		/// Gets the value of one of this object's properties.
		/// </summary>
		public string GetString(FieldNameConstants field, string defaultValue)
		{
			object o = this.GetValue(field, defaultValue);
			if (o is string)
			{
				return (string)o;
			}
			else
			{
				return o.ToString();
			}
		}

		#endregion

		#region SetValue

		/// <summary>
		/// Assigns a value to a field on this object.
		/// </summary>
		/// <param name="field">The field to set</param>
		/// <param name="newValue">The new value to assign to the field</param>
		public void SetValue(FieldNameConstants field, object newValue)
		{
			SetValue(field, newValue, false);
		}

		/// <summary>
		/// Assigns a value to a field on this object.
		/// </summary>
		/// <param name="field">The field to set</param>
		/// <param name="newValue">The new value to assign to the field</param>
		/// <param name="fixLength">Determines if the length should be truncated if too long. When false, an error will be raised if data is too large to be assigned to the field.</param>
		public void SetValue(FieldNameConstants field, object newValue, bool fixLength)
		{
			if (field == FieldNameConstants.CategoryId)
			{
				if (newValue == null)
				{
					this.CategoryId = null;
				}
				else
				{
					if(Widgetsphere.Core.Util.ReflectionHelper.ImplementsInterface(newValue, typeof(IWrappingClass)))
					{
						this.CategoryId = ((Category)newValue).CategoryId;
					} else if(newValue is IPrimaryKey)
					{
						this.CategoryId = ((CategoryPrimaryKey)newValue).CategoryId;
					} else
					if (newValue is string)
					{
						this.CategoryId = int.Parse((string)newValue);
					} else if (!(newValue is int?)) {
						this.CategoryId = int.Parse(newValue.ToString());
					}
					else if (newValue is IBusinessObject)
					{
						throw new Exception("An invalid object of type 'IBusinessObject' was passed in. Perhaps a relationship was not enforced correctly.");
					}
					else
					this.CategoryId = (int?)newValue;
				}
				return;
			}
			else if (field == FieldNameConstants.UnitsOnOrder)
			{
				if (newValue == null)
				{
					this.UnitsOnOrder = null;
				}
				else
				{
					if (newValue is string)
					{
						this.UnitsOnOrder = short.Parse((string)newValue);
					} else if (!(newValue is short?)) {
						this.UnitsOnOrder = short.Parse(newValue.ToString());
					}
					else if (newValue is IBusinessObject)
					{
						throw new Exception("An invalid object of type 'IBusinessObject' was passed in. Perhaps a relationship was not enforced correctly.");
					}
					else
					this.UnitsOnOrder = (short?)newValue;
				}
				return;
			}
			else if (field == FieldNameConstants.UnitsInStock)
			{
				if (newValue == null)
				{
					this.UnitsInStock = null;
				}
				else
				{
					if (newValue is string)
					{
						this.UnitsInStock = short.Parse((string)newValue);
					} else if (!(newValue is short?)) {
						this.UnitsInStock = short.Parse(newValue.ToString());
					}
					else if (newValue is IBusinessObject)
					{
						throw new Exception("An invalid object of type 'IBusinessObject' was passed in. Perhaps a relationship was not enforced correctly.");
					}
					else
					this.UnitsInStock = (short?)newValue;
				}
				return;
			}
			else if (field == FieldNameConstants.UnitPrice)
			{
				if (newValue == null)
				{
					this.UnitPrice = null;
				}
				else
				{
					if (newValue is string)
					{
						this.UnitPrice = decimal.Parse((string)newValue);
					} else if (!(newValue is decimal?)) {
						this.UnitPrice = decimal.Parse(newValue.ToString());
					}
					else if (newValue is IBusinessObject)
					{
						throw new Exception("An invalid object of type 'IBusinessObject' was passed in. Perhaps a relationship was not enforced correctly.");
					}
					else
					this.UnitPrice = (decimal?)newValue;
				}
				return;
			}
			else if (field == FieldNameConstants.SupplierId)
			{
				if (newValue == null)
				{
					this.SupplierId = null;
				}
				else
				{
					if(Widgetsphere.Core.Util.ReflectionHelper.ImplementsInterface(newValue, typeof(IWrappingClass)))
					{
						this.SupplierId = ((Supplier)newValue).SupplierId;
					} else if(newValue is IPrimaryKey)
					{
						this.SupplierId = ((SupplierPrimaryKey)newValue).SupplierId;
					} else
					if (newValue is string)
					{
						this.SupplierId = int.Parse((string)newValue);
					} else if (!(newValue is int?)) {
						this.SupplierId = int.Parse(newValue.ToString());
					}
					else if (newValue is IBusinessObject)
					{
						throw new Exception("An invalid object of type 'IBusinessObject' was passed in. Perhaps a relationship was not enforced correctly.");
					}
					else
					this.SupplierId = (int?)newValue;
				}
				return;
			}
			else if (field == FieldNameConstants.ReorderLevel)
			{
				if (newValue == null)
				{
					this.ReorderLevel = null;
				}
				else
				{
					if (newValue is string)
					{
						this.ReorderLevel = short.Parse((string)newValue);
					} else if (!(newValue is short?)) {
						this.ReorderLevel = short.Parse(newValue.ToString());
					}
					else if (newValue is IBusinessObject)
					{
						throw new Exception("An invalid object of type 'IBusinessObject' was passed in. Perhaps a relationship was not enforced correctly.");
					}
					else
					this.ReorderLevel = (short?)newValue;
				}
				return;
			}
			else if (field == FieldNameConstants.QuantityPerUnit)
			{
				if (newValue == null)
				{
					this.QuantityPerUnit = null;
				}
				else
				{
					string v = newValue.ToString();
					if (fixLength)
					{
						int fieldLength = GetFieldLength(FieldNameConstants.QuantityPerUnit);
						if (v.Length > fieldLength) v = v.Substring(0, fieldLength);
					}
					this.QuantityPerUnit = v;
				}
				return;
			}
			else if (field == FieldNameConstants.ProductName)
			{
				if (newValue == null)
				{
					this.ProductName = null;
				}
				else
				{
					string v = newValue.ToString();
					if (fixLength)
					{
						int fieldLength = GetFieldLength(FieldNameConstants.ProductName);
						if (v.Length > fieldLength) v = v.Substring(0, fieldLength);
					}
					this.ProductName = v;
				}
				return;
			}
			else if (field == FieldNameConstants.ProductId)
			{
				throw new Exception("Field '" + field.ToString() + "' is a primary key and cannot be set!");
			}
			else if (field == FieldNameConstants.Discontinued)
			{
				if (newValue == null)
				{
					throw new Exception("Field 'Discontinued' does not allow null values!");
				}
				else
				{
					if (newValue is string)
					{
						this.Discontinued = bool.Parse((string)newValue);
					} else if (!(newValue is bool)) {
						this.Discontinued = bool.Parse(newValue.ToString());
					}
					else if (newValue is IBusinessObject)
					{
						throw new Exception("An invalid object of type 'IBusinessObject' was passed in. Perhaps a relationship was not enforced correctly.");
					}
					else
					this.Discontinued = (bool)newValue;
				}
				return;
			}
			throw new Exception("Field '" + field.ToString() + "' not found!");
		}

		#endregion

		#region GetFieldLength

		/// <summary>
		/// Determines the length of the specified field if it can be set.
		/// </summary>
		public int GetFieldLength(Product.FieldNameConstants field)
		{
			if(field == FieldNameConstants.QuantityPerUnit) return 20;
			if(field == FieldNameConstants.ProductName) return 40;
			//Catch all for all other data types
			return -1;
		}
		#endregion

		#region Clone

		/// <summary>
		/// Create a copy of this object.
		/// </summary>
		public virtual IBusinessObject Clone()
		{
			lock (this)
			{
				if (!this.IsParented) throw new Exception("The current item must be parented.");
				Product newItem = null;
				lock (this.ParentCollection.SubDomain)
				{
					newItem = new Product(this.ParentCollection.wrappedClass.NewItem());
				}
				this.FillClone(newItem);
				return newItem;
			}
		}

		/// <summary>
		/// Create a copy of this object.
		/// <param name="productid">The productid field</param>
		/// </summary>
		public virtual IBusinessObject Clone(int productid)
		{
			lock (this)
			{
				if (!this.IsParented) throw new Exception("The current item must be parented.");
				Product newItem = null;
				lock (this.ParentCollection.wrappedClass.SubDomain)
				{
				newItem = new Product(this.ParentCollection.wrappedClass.NewItem(productid));
				}
				this.FillClone(newItem);
				return newItem;
			}
		}

		private void FillClone(Product newItem)
		{
			lock (this)
			{
				lock (newItem)
				{
					newItem.CategoryId = this.CategoryId;
					newItem.UnitsOnOrder = this.UnitsOnOrder;
					newItem.UnitsInStock = this.UnitsInStock;
					newItem.UnitPrice = this.UnitPrice;
					newItem.SupplierId = this.SupplierId;
					newItem.ReorderLevel = this.ReorderLevel;
					newItem.QuantityPerUnit = this.QuantityPerUnit;
					newItem.ProductName = this.ProductName;
					newItem.Discontinued = this.Discontinued;
				}
			}
		}

		object ICloneable.Clone()
		{
			return this.Clone();
		}

		#endregion

		#region Helper Methods

		string IBusinessObject.GetFriendlyName(Enum field)
		{
			return "";
		}

		/// <summary>
		/// Gets the maximum size of the field value.
		/// </summary>
		public static int GetMaxLength(FieldNameConstants field)
		{
			switch (field)
			{
				case FieldNameConstants.CategoryId:
					return 0;
				case FieldNameConstants.Discontinued:
					return 0;
				case FieldNameConstants.ProductId:
					return 0;
				case FieldNameConstants.ProductName:
					return 40;
				case FieldNameConstants.QuantityPerUnit:
					return 20;
				case FieldNameConstants.ReorderLevel:
					return 0;
				case FieldNameConstants.SupplierId:
					return 0;
				case FieldNameConstants.UnitPrice:
					return 0;
				case FieldNameConstants.UnitsInStock:
					return 0;
				case FieldNameConstants.UnitsOnOrder:
					return 0;
			}
			return 0;
		}

		int IBusinessObject.GetMaxLength(Enum field)
		{
			return GetMaxLength((FieldNameConstants)field);
		}

		string IBusinessObject.GetMask(Enum field)
		{
			return "";
		}

		/// <summary>
		/// Select a single object from this collection by its primary key.
		/// </summary>
		public static Product SelectUsingPK(int productid)
		{
			return SelectUsingPK(productid, "");
		}

		/// <summary>
		/// Select a single object from this collection by its primary key.
		/// </summary>
		public static Product SelectUsingPK(int productid, string modifier)
		{
			ProductCollection product = ProductCollection.SelectUsingPK(productid, modifier);
			if (product.Count > 1) throw new Exception("Product primary key returned more than one value.");
			else if (product.Count == 0) return null;
			else return product[0];
		}

		#endregion

		#region IBusinessObject Members

		IPrimaryKey IBusinessObject.PrimaryKey
		{
			get { return this.PrimaryKey; }
		}

		object IBusinessObject.GetValue(Enum field)
		{
			return this.GetValue((FieldNameConstants)field);
		}

		object IBusinessObject.GetValue(Enum field, object defaultValue)
		{
			return this.GetValue((FieldNameConstants)field, defaultValue);
		}

		double IBusinessObject.GetDouble(Enum field)
		{
			return this.GetDouble((FieldNameConstants)field);
		}

		double IBusinessObject.GetDouble(Enum field, double defaultValue)
		{
			return this.GetDouble((FieldNameConstants)field, defaultValue);
		}

		DateTime IBusinessObject.GetDateTime(Enum field)
		{
			return this.GetDateTime((FieldNameConstants)field);
		}

		DateTime IBusinessObject.GetDateTime(Enum field, DateTime defaultValue)
		{
			return this.GetDateTime((FieldNameConstants)field, defaultValue);
		}

		int IBusinessObject.GetInteger(Enum field)
		{
			return this.GetInteger((FieldNameConstants)field);
		}

		int IBusinessObject.GetInteger(Enum field, int defaultValue)
		{
			return this.GetInteger((FieldNameConstants)field, defaultValue);
		}

		string IBusinessObject.GetString(Enum field)
		{
			return this.GetString((FieldNameConstants)field);
		}

		string IBusinessObject.GetString(Enum field, string defaultValue)
		{
			return this.GetString((FieldNameConstants)field, defaultValue);
		}

		void IPersistableBusinessObject.SetValue(Enum field, object newValue)
		{
			this.SetValue((FieldNameConstants)field, newValue);
		}

		Enum IBusinessObject.Container
		{
			get { return this.Container; }
		}

		/// <summary>
		/// Determines if all of the fields for the specified object exactly matches the current object.
		/// </summary>
		/// <param name="item">The object to compare</param>
		public override bool IsEquivalent(IBusinessObject item)
		{
			if (item == null) return false;
			if (!(item is Product)) return false;
			Product o = item as Product;
			return (
				o.CategoryId == this.CategoryId &&
				o.UnitsOnOrder == this.UnitsOnOrder &&
				o.UnitsInStock == this.UnitsInStock &&
				o.UnitPrice == this.UnitPrice &&
				o.SupplierId == this.SupplierId &&
				o.ReorderLevel == this.ReorderLevel &&
				o.QuantityPerUnit == this.QuantityPerUnit &&
				o.ProductName == this.ProductName &&
				o.ProductId == this.ProductId &&
				o.Discontinued == this.Discontinued
				);
		}

		#endregion

		#region IAuditable Members

		string IAuditable.CreatedBy
		{
			get { return this.CreatedBy; }
		}

		DateTime? IAuditable.CreatedDate
		{
			get { return this.CreatedDate; }
		}

		bool IAuditable.IsCreateAuditImplemented
		{
			get { return true; }
		}

		bool IAuditable.IsModifyAuditImplemented
		{
			get { return true; }
		}

		bool IAuditable.IsTimestampAuditImplemented
		{
			get { return true; }
		}

		string IAuditable.ModifiedBy
		{
			get { return this.ModifiedBy; }
		}

		DateTime? IAuditable.ModifiedDate
		{
			get { return this.ModifiedDate; }
		}

		byte[] IAuditable.TimeStamp
		{
			get { return this.TimeStamp; }
		}

		#endregion

	}

}
